package com.qfedu.mbti.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qfedu.mbti.config.RedisKeyConfig;
import com.qfedu.mbti.dao.MbtiExamDao;
import com.qfedu.mbti.dao.MbtiQuestionDao;
import com.qfedu.mbti.dao.UserDao;
import com.qfedu.mbti.dao.UserLogDao;
import com.qfedu.mbti.entity.MbtiExam;
import com.qfedu.mbti.entity.MbtiQuestion;
import com.qfedu.mbti.entity.User;
import com.qfedu.mbti.entity.UserLog;
import com.qfedu.mbti.service.MbtiExamService;
import com.qfedu.mbti.vo.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * MRTI测试表(MbtiExam)表服务实现类
 *
 * @author makejava
 * @since 2024-11-04 11:43:41
 */
@Service("mbtiExamService")
@RequiredArgsConstructor
@Slf4j
public class MbtiExamServiceImpl implements MbtiExamService {
    private final MbtiExamDao dao;
    private final MbtiQuestionDao questionDao;
    private final UserLogDao logDao;
    private final UserDao userDao;
    private final StringRedisTemplate stringRedisTemplate;

    private final String KEY="08c843f7a4b85e5cb5753752edf8ea0d";

    @Transactional
    @Override
    public R createExam(String token) {
        //1.对应用户
        String uid=stringRedisTemplate.opsForValue().get(RedisKeyConfig.USER_TOKEN+token);
        User user=userDao.selectById(uid);
        if(user!=null && user.getNum()>0) {
            //2.创建测试对象
            MbtiExam exam = new MbtiExam(Integer.parseInt(uid), "MBTI人格测试", "MBTI");
            if (dao.insert(exam) > 0) {
                //3.请求第三方接口 Hutool HttpUtil 请求第三方接口
                //准备参数
                Map<String, Object> param = new HashMap<>();
                param.put("key", KEY);
                //执行对应的请求 获取响应
                String json = HttpUtil.post("http://apis.juhe.cn/fapig/character_test/questions", param);
                List<MbtiQuestion> questionList = new ArrayList<>();
                //校验 接口是否返回成功
                if (StringUtils.hasLength(json)) {
                    //验证本次请求响应是否成功
                    JSONObject jo1 = new JSONObject(json);
                    if ("success".equals(jo1.getStr("reason"))) {
                        //返回成功
                        //获取对应的测试题
                        JSONArray ja = jo1.getJSONArray("result");
                        for (int i = 0; i < ja.size(); i++) {
                            JSONObject jo2 = ja.getJSONObject(i);
                            MbtiQuestion question = new MbtiQuestion(exam.getId(), jo2.getStr("q"),
                                    jo2.getStr("a"), jo2.getStr("b"), jo2.getStr("ia"), jo2.getStr("ib"));

                            questionList.add(question);
                        }
                    }
                }
                if (questionList.size() == 0) {
                    //请求第三方接口失败，数据库   随机读取 随机排序
                    List<MbtiQuestion> list = questionDao.selectRandom();
                    list.forEach(q -> {
                        MbtiQuestion question = new MbtiQuestion();
                        BeanUtils.copyProperties(q, question);
                        question.setMeid(exam.getId());
                        question.setAnswer(null);
                        question.setCreateTime(new Date());
                        question.setUpdateTime(new Date());
                        questionList.add(question);

                    });
                }
                //批量新增测试题
                questionDao.insert(questionList);
                //记录日志
                logDao.insert(new UserLog(exam.getUid(), "创建测试", "创建MBTI测试成功"));
                //考试次数-1
                user.setPassword(null);
                user.setUpdateTime(new Date());
                user.setNum(user.getNum()-1);
                userDao.updateById(user);


                //成功 返回 考试ID
                return R.ok(exam.getId());
            }
        }

        return R.fail("亲，创建测试失败！");
    }

    @Override
    public R startExam(Integer id) {
        MbtiExam exam=dao.selectById(id);
        if(exam!=null && exam.getStatus().equals("未开始")) {
            LambdaQueryWrapper<MbtiQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(MbtiQuestion::getMeid,exam.getId());
            wrapper.orderByAsc(MbtiQuestion::getId);
            //更改状态 进行中
            exam.setTitle(null);
            exam.setType(null);
            exam.setUid(null);
            exam.setStatus("进行中");
            exam.setUpdateTime(new Date());
            dao.updateById(exam);

            return R.ok(questionDao.selectList(wrapper));
        }
        return R.fail("亲，请检查测试的状态！");
    }

    @Override
    public R endExam(Integer id) {
        MbtiExam exam=dao.selectById(id);
        if(exam!=null && exam.getStatus().equals("进行中")) {
            //2.拼接 答案
            LambdaQueryWrapper<MbtiQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(MbtiQuestion::getMeid,id);
            wrapper.orderByAsc(MbtiQuestion::getId);
            List<MbtiQuestion> questions=questionDao.selectList(wrapper);
            log.info("问题-{}",questions);
            StringBuffer answers=new StringBuffer();
            for (int i = 0; i < questions.size(); i++) {
                answers.append(questions.get(i).getAnswer()+",");
            }
            log.info("初始答案={}",answers);
            if(answers.length()>0) {
                answers.deleteCharAt(answers.length() - 1);

                log.info("答案={}",answers);
                //3.请求第三方接口
                //准备参数
                Map<String, Object> param = new HashMap<>();
                param.put("key", KEY);
                param.put("answers", answers);

                //执行对应的请求 获取响应
                String json = HttpUtil.post("http://apis.juhe.cn/fapig/character_test/analysis", param);
                log.info("接口反馈={}",json);
                if (StringUtils.hasLength(json)) {
                    //json解析
                    JSONObject jo1 = new JSONObject(json);
                    if (jo1.getStr("reason").equals("success")) {
                        JSONObject jo2 = jo1.getJSONObject("result");
                        exam.setAlphabet(jo2.getStr("alphabet"));
                        exam.setVocabulary(jo2.getStr("vocabulary"));
                        exam.setOccupation(jo2.getStr("occupation"));
                        exam.setSummarize(jo2.getJSONArray("summarize").getStr(0));
                        exam.setDescc(jo2.getJSONArray("desc").getStr(0));
                        StringBuffer buffer = new StringBuffer();
                        JSONArray array = jo2.getJSONArray("characteristic");
                        for (int i = 0; i < array.size(); i++) {
                            buffer.append(array.getJSONObject(i).getStr("title") + ",");
                        }
                        exam.setCharacteristic(buffer.toString());
                        exam.setStatus("已结束");
                        exam.setUpdateTime(new Date());
                        if (dao.updateById(exam) > 0) {

                            //记录日志
                            logDao.insert(new UserLog(exam.getUid(), "结束MBTI测试", "完成了MBTI测试，本次人格为" + exam.getOccupation()));

                            return R.ok(exam);
                        }
                    }
                }
            }
        }
        return R.fail("亲，网络异常，结束测试失败！");
    }

    @Override
    public R queryMy(String token) {
        LambdaQueryWrapper<MbtiExam> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(MbtiExam::getUid,stringRedisTemplate.opsForValue().get(RedisKeyConfig.USER_TOKEN+token));
        wrapper.orderByDesc(MbtiExam::getCreateTime);
        return R.ok(dao.selectList(wrapper));
    }
}

